package com.may.wlrj.services;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.context.request.async.DeferredResult;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.may.wlrj.dao.RoleDAO;
import com.may.wlrj.dao.UserDAO;
import com.may.wlrj.dao.UserRoleDAO;
import com.may.wlrj.entity.OrganizationEntity;
import com.may.wlrj.entity.RightRejectEntity;
import com.may.wlrj.entity.RoleEntity;
import com.may.wlrj.entity.RoleRightEntity;
import com.may.wlrj.entity.UserEntity;
import com.may.wlrj.entity.UserLogEntity;
import com.may.wlrj.entity.UserRoleEntity;
import com.may.wlrj.util.XinLongUtil;

@Service
@Transactional(rollbackFor=Exception.class)
public class RoleService {
	private Logger log = Logger.getLogger(RoleService.class);
	private RoleDAO roleDao;
	@Autowired
	public void setRoleDAO(RoleDAO roleDao) {
		this.roleDao = roleDao;
	}
	private UserDAO userDao;
	@Autowired
    public void setUserDao(UserDAO userDao){
        this.userDao =userDao;
    }
	
	private UserRoleDAO userroleDao;
	@Autowired
	public void setUserRoleDAO(UserRoleDAO userroleDao) {
		this.userroleDao = userroleDao;
	}
	
	public String getRolelist(HttpSession session) throws JsonProcessingException{
		UserEntity sentity = (UserEntity)session.getAttribute("USER_SESSION");
    	ObjectMapper mapper = new ObjectMapper(); 
    	ObjectNode resjson = mapper.createObjectNode(); 
	
    	List<RoleEntity> proles = null;
    	//找出当前及下级机构所有角色
    	List<OrganizationEntity> suborgs = roleDao.findSubOrg(sentity.getOrg_id());    	
    	List<RoleEntity> roles = roleDao.findsubAll(suborgs);
    	//找出上级机构的角色
    	List<OrganizationEntity> porgs = roleDao.findParentOrgs(sentity.getOrg_id());
		if(porgs != null && porgs.size() > 0){
			proles = roleDao.findPAll(porgs);
    	}
		if(proles != null && proles.size() > 0){
			roles.addAll(proles);
		}
    	ArrayNode rootnode = mapper.createArrayNode();
    	if(roles.size() > 0){
    		ObjectNode tjson = null;
    		for(RoleEntity role : roles){
    			tjson = mapper.createObjectNode();
    			tjson.put("rolename", role.getRolename());
    			tjson.put("roleid", role.getId());
    			tjson.put("org_id", role.getOrg_id());
    			tjson.put("subflags", role.getSubflags());
    			tjson.put("orgname", role.getOrgname());
    			tjson.put("createtime", role.getCreatetime());
    			tjson.put("updatetime", role.getUpdatetime());
    			rootnode.add(tjson);
        	}
    	}
    	resjson.put("code", "0");
    	resjson.put("count", roles.size());
    	resjson.put("msg", "");
    	resjson.put("data", rootnode);
		return mapper.writeValueAsString(resjson);
	}
	
	public String getRoles(HttpSession session) throws JsonProcessingException{
    	UserEntity sentity = (UserEntity)session.getAttribute("USER_SESSION");
    	ObjectMapper mapper = new ObjectMapper(); 
 
    	List<RoleEntity> proles = null;
    	//找出当前及下级机构所有角色
    	List<OrganizationEntity> suborgs = roleDao.findSubOrg(sentity.getOrg_id());    	
    	List<RoleEntity> roles = roleDao.findsubAll(suborgs);
    	//找出上级机构的角色
    	List<OrganizationEntity> porgs = roleDao.findParentOrgs(sentity.getOrg_id());
		if(porgs != null && porgs.size() > 0){
			proles = roleDao.findPAll(porgs);
    	}
		if(proles != null && proles.size() > 0){
			roles.addAll(proles);
		}
    	
		return mapper.writeValueAsString(roles);
	}
	
	public void _insertandupdateRole(DeferredResult<String> deferredResult,String jsonstr, HttpServletRequest request, HttpSession session) throws JsonProcessingException{
		XinLongUtil.xinLongUtil.printlog(log,jsonstr);
		UserEntity sentity = (UserEntity)session.getAttribute("USER_SESSION");	
		String remoteaddr = XinLongUtil.getRemoteAddr(request);
		ObjectMapper mapper = new ObjectMapper(); 
    	ObjectNode resjson = mapper.createObjectNode();

    	String rolename = "";
    	String roleid = "";
    	String ckname = "";
		int subflags = 0;
		List<String> rights = null;
		com.fasterxml.jackson.databind.JsonNode rootNode;
		try {
			rootNode = mapper.readTree(jsonstr);
			rolename = rootNode.get("rolename").asText();
			ckname = rootNode.get("ckname").asText();
			subflags = rootNode.get("subflags").asInt();
			roleid = rootNode.get("roleid").asText();
			JsonNode value = rootNode.findValue("children");
			rights = mapper.readValue(value.toString(),new TypeReference<List<String>>() { });
			
		} catch (IOException e1) {
			resjson.put("status", "2");
			resjson.put("desc", "解析上传数据异常!");
			deferredResult.setResult(mapper.writeValueAsString(resjson));
    		return;
		}	
		
    	//权限判断
		/*resjson = XinLongUtil.OptAuth("",jsonstr, sentity);
		if(!resjson.get("status").asText().equals("1210")){
			deferredResult.setResult(mapper.writeValueAsString(resjson));
    		return;
		}*/
		
		Date date = new Date();
		SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		
		UserLogEntity ulog = new UserLogEntity();
		ulog.setId(UUID.randomUUID().toString().replace("-", ""));
		ulog.setRemote_addr(remoteaddr);
		ulog.setCreatetime(dateFormat.format(date));
		ulog.setArgs_json(jsonstr);
		ulog.setRname("系统管理/角色管理/新增修改");
		ulog.setCreateusername(sentity.getUsername());
		ulog.setUserid(sentity.getId());
		ulog.setMethod("insertandupdateRole");
		ulog.setCreate_check_userid(ckname);
		ulog.setOrgid(sentity.getOrg_id());
		//判断角色是否新建
		if(roleid.equals("")){
			//开始创建角色
			XinLongUtil.xinLongUtil.printlog(log,"----------->>开始创建角色");
			RoleEntity rentity = new RoleEntity();
			rentity.setCreate_username(sentity.getUsername());
			rentity.setCreatetime(dateFormat.format(date));
			rentity.setOrg_id(sentity.getOrg_id());
			rentity.setRolename(rolename);
			rentity.setSubflags(subflags);
			rentity.setId(UUID.randomUUID().toString().replace("-", ""));
			int rflag = roleDao.insertRole(rentity);
			if( rflag == 0){
				resjson.put("status", "4");
				resjson.put("desc", "添加角色失败!");
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}else if(rflag == -1 ){
				resjson.put("status", "4");
				resjson.put("desc", "添加角色失败,角色名重复!");
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			//绑定角色权限
			ObjectNode bdres = bindRoleAndRights(rights,rentity.getId());
			if(bdres.get("status").asText().equals("0")){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			ulog.setDescriptor("新建角色:" + rolename);
			ulog.setProceed("操作成功");
			XinLongUtil.saveUserLog(ulog);
		}else{
			//更新角色信息
			XinLongUtil.xinLongUtil.printlog(log,"----------->>更新角色信息");
			RoleEntity rentity = roleDao.findByRoleId(roleid);
			if(rentity == null){
				resjson.put("status", "6");
				resjson.put("desc", "获取角色信息失败!");
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			if(!sentity.getOrg_id().equalsIgnoreCase(rentity.getOrg_id())){
				resjson.put("status", "6");
				resjson.put("desc", "该角色需由其创建的机构人员进行编辑!");
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			rentity.setUpdatetime(dateFormat.format(date));
			rentity.setUpdate_username(sentity.getUsername());
			rentity.setRolename(rolename);
			rentity.setSubflags(subflags);
			int rflag = roleDao.updateRole(rentity);
			if( rflag == 0){
				resjson.put("status", "4");
				resjson.put("desc", "更新角色信息失败!");
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}else if(rflag == -1 ){
				resjson.put("status", "4");
				resjson.put("desc", "更新角色信息失败,角色名重复!");
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			//删除旧的权限
			if(roleDao.deleterightsbyid(roleid) == 0){
				resjson.put("status", "7");
				resjson.put("desc", "更新角色权限失败!");
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			//更新角色权限
			ObjectNode rejres = bindRoleAndRights(rights,rentity.getId());
			if( rejres.get("status").asText().equals("0")){
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				deferredResult.setResult(mapper.writeValueAsString(resjson));
	    		return;
			}
			ulog.setDescriptor("编辑角色:" + rolename);
			ulog.setProceed("操作成功");
			XinLongUtil.saveUserLog(ulog);
		}
		
		
		resjson.put("status", "1");
		resjson.put("desc", "编辑角色成功!");
		deferredResult.setResult(mapper.writeValueAsString(resjson));
		return;
	}
	
	
	
	public ObjectNode bindRoleAndRights(List<String> rights, String roleid){
		ObjectMapper mapper = new ObjectMapper(); 
    	ObjectNode resjson = mapper.createObjectNode();
		RoleRightEntity rrentity = null;
		try{
			for(String rid : rights){
				//判断功能互斥
				resjson = isRejected(rid,rights);
				if(resjson.get("status").asText().equals("0")){
					return resjson;
				}
				rrentity = new RoleRightEntity();
				rrentity.setId(UUID.randomUUID().toString().replace("-", ""));
				rrentity.setRole_id(roleid);
				rrentity.setRight_id(rid);
				roleDao.insertRoleAndRight(rrentity);
			}
		}catch(Exception ex){
			resjson.put("status", "0");
			resjson.put("desc", ex.getMessage());
			return resjson;
		}
		resjson.put("status", "1");
		return resjson;
	}
	
	private ObjectNode isRejected(String rightid,List<String> rights){
		ObjectMapper mapper = new ObjectMapper(); 
    	ObjectNode resjson = mapper.createObjectNode();
    	int flag = 0;
    	StringBuffer sb = new StringBuffer();
		List<RightRejectEntity> rejects = roleDao.findRejectdescByid(rightid);
		if(rejects != null){
			for(RightRejectEntity rej : rejects){
				if(rights.contains(rej.getReject_right_id())){
					flag = 1;
					resjson.put("status", "0");
					sb.append(roleDao.findRightname(rightid) + "与" + roleDao.findRightname(rej.getReject_right_id()) + "功能互斥!");
					sb.append("<br/>");
					//return resjson;
				}
			}
			
		}
		if(flag == 0){
			resjson.put("status", "1");
		}
		resjson.put("desc", sb.toString());
		
		return resjson;
	}
	
	public String getRoleRights(String jsonstr) throws JsonProcessingException{
		XinLongUtil.xinLongUtil.printlog(log,jsonstr);
		ObjectMapper mapper = new ObjectMapper(); 
    	ObjectNode resjson = mapper.createObjectNode();
    	com.fasterxml.jackson.databind.JsonNode rootNode;
    	String roleid = "";
		try {
			resjson.put("status", "1");
			resjson.put("desc", "成功!");
			rootNode = mapper.readTree(jsonstr);
			roleid =rootNode.get("roleid").asText();

			List<RoleRightEntity> rights = roleDao.getRoleRights(roleid);
			if(rights != null && rights.size() > 0){
				ObjectNode json = null;
				ArrayNode rootnode = mapper.createArrayNode();
				for(RoleRightEntity rid : rights){
					json = mapper.createObjectNode();
					json.put("rightid", rid.getRight_id());
					rootnode.add(json);
				}
				resjson.put("children", rootnode);
			}
		} catch (IOException e1) {
			resjson.put("status", "2");
			resjson.put("desc", "解析上传数据异常!");
			return mapper.writeValueAsString(resjson);
		}	
		
		return mapper.writeValueAsString(resjson);
	}
	
	public void _RoleDelete(DeferredResult<String> deferredResult,String jsonstr,HttpServletRequest request ,HttpSession session) throws JsonProcessingException{
		XinLongUtil.xinLongUtil.printlog(log,jsonstr);
		ObjectMapper mapper = new ObjectMapper();
		ObjectNode resjson = mapper.createObjectNode();  
		String roleid ="";
		String rolename = "";
		String roleorg = "";
		String ckname ="";
    	UserEntity sentity = (UserEntity)session.getAttribute("USER_SESSION");
    	String remoteaddr = XinLongUtil.getRemoteAddr(request);
    	com.fasterxml.jackson.databind.JsonNode rootNode;
		try {
			rootNode = mapper.readTree(jsonstr);
			roleid =rootNode.get("roleid").asText();
			rolename =rootNode.get("roleid").asText();
			roleorg =rootNode.get("role_org").asText();
			ckname =rootNode.get("ckname").asText();
		} catch (IOException e) {
			resjson.put("status", "0");
    		resjson.put("desc", "上传数据解析异常!");
    		deferredResult.setResult(mapper.writeValueAsString(resjson));
    		return;
		}
		if(!sentity.getOrg_id().equalsIgnoreCase(roleorg)){
			resjson.put("status", "0");
			resjson.put("desc", "该角色需由其创建的机构人员进行删除!");
			deferredResult.setResult(mapper.writeValueAsString(resjson));
			return;
		}
		//权限判断
		/*resjson = XinLongUtil.OptAuth("",jsonstr, sentity);
		if(!resjson.get("status").asText().equals("1210")){
    		deferredResult.setResult(mapper.writeValueAsString(resjson));
			return;
		}*/
		Date date = new Date();
		SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		
		UserLogEntity ulog = new UserLogEntity();
		ulog.setId(UUID.randomUUID().toString().replace("-", ""));
		ulog.setRemote_addr(remoteaddr);
		ulog.setCreatetime(dateFormat.format(date));
		ulog.setArgs_json(jsonstr);
		ulog.setRname("系统管理/角色管理/删除");
		ulog.setCreateusername(sentity.getUsername());
		ulog.setUserid(sentity.getId());
		ulog.setMethod("RoleDelete");
		ulog.setOrgid(sentity.getOrg_id());
		ulog.setCreate_check_userid(ckname);
		//判断有无用户指向该角色
		List<UserRoleEntity>  urlist = userroleDao.findByRoleId(roleid);
		if(urlist.size() > 0){
			resjson.put("status", "0");
    		resjson.put("desc", "该角色有其它引用,无法删除!");
    		deferredResult.setResult(mapper.writeValueAsString(resjson));
    		return;
		}
		roleDao.closeForeignKey();
		//删除tbl_role_right表引用
		if(roleDao.deleterightsbyid(roleid) == 0){
			
		}
    	if(roleDao.deletebyid(roleid) == 0){
    		resjson.put("status", "0");
    		resjson.put("desc", "删除角色失败!");
    		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    		deferredResult.setResult(mapper.writeValueAsString(resjson));
    		return;
    	}
    	roleDao.openForeignKey();
    	ulog.setDescriptor("删除角色:" + rolename);
		ulog.setProceed("操作成功");
		XinLongUtil.saveUserLog(ulog);
    	resjson.put("status", "1");
		resjson.put("desc", "成功!");
		deferredResult.setResult(mapper.writeValueAsString(resjson));
		return;
    }
}
